package com.u.finance.loans.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.u.finance.loans.entity.Loans;
import com.u.finance.loans.entity.User;
import com.u.finance.loans.entity.UserScore;
import com.u.finance.loans.feign.PayFeign;
import com.u.finance.loans.mapper.LoansMapper;
import com.u.finance.loans.model.LoanApplyForm;
import com.u.finance.loans.service.ILoansService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.u.finance.loans.service.IRepaymentScheduleService;
import com.u.finance.loans.service.IUserScoreService;
import com.u.finance.loans.service.IUserService;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Alex Wu
 * @since 2025-03-28
 */
@Service
public class LoansServiceImpl extends ServiceImpl<LoansMapper, Loans> implements ILoansService {


    @Autowired
    private IUserScoreService userScoreService;

    @Autowired
    private IUserService usersService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private IUserService userService;

    @Autowired
    private PayFeign payFeign;

    @Autowired
    private IRepaymentScheduleService repaymentScheduleService;

    @Override
    public Long getQuotaLimit(String userId) {
        String role = (String) redisTemplate.opsForValue().get("user_score_" + userId);
        if(role != null){
            return Long.parseLong(role);
        }
        Long canQuota = 0L;
        // 查询不出来再查数据库
        UserScore userScore = userScoreService.getOne(new QueryWrapper<UserScore>().eq("userId", userId));
        if(userScore != null){
            if(userScore.getRole() == 4){
                canQuota =  4000L;
            }else if(userScore.getRole() == 3){
                canQuota = 3000L;
            }else if(userScore.getRole() == 2){
                canQuota =  2000L;
            }
        }
        User user = usersService.getById(userId);
        if(user.getIsVip() == 1){
            canQuota =  4000L;
        }
        redisTemplate.opsForValue().set("user:quota:" + userId, canQuota);
        return canQuota;
    }

    @Override
    public Boolean applyLoan(LoanApplyForm loanApplyForm) {
        // 解密凭证
        if(usersService.decodeCertificate(loanApplyForm.getCertifyNo()) == null){
            return false;
        }
        Long canQuta = (Long) redisTemplate.opsForValue().get("user:quota:" + loanApplyForm);
        if(canQuta < loanApplyForm.getAmount()){
            return false;
        }

        Loans loans = new Loans();
        Long loansId = System.currentTimeMillis(); // or any other logic to generate the ID
        loans.setId(loansId);
        loans.setUserId(loanApplyForm.getUserId());
        loans.setAmount(loans.getAmount());

        // 2. 发送事务信息（消息暂不投递） 发送审核, 埋点信息, Flink 计算, AI审核

        Message message = MessageBuilder.withPayload(JSON.toJSONString(loans)).setHeader("loans", loansId).build();

        TransactionSendResult result=rocketMQTemplate.sendMessageInTransaction(
                "tx-loans-topic", // 主题
                message, // 消息体
                loans // 事务参数（会传给监听器）
        );

        /*
        // 发送审核, 埋点信息, Flink 计算, AI审核
        rocketMQTemplate.convertAndSend("loan_apply", loans);*/
        return result.isTraceOn();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveInTransaction(Loans beans) {
        // 1. 保存申请表
        this.save(beans);
//        int a = 1/0 ; // 模拟异常
    }

    @GlobalTransactional
    @Override
    public void payOut(Long id){
        String xid = RootContext.getXID();
        System.out.println("分布式事务ID: " + xid);
        Loans loans = this.getById(id);

        boolean isSuccess = payFeign.transferCount(loans.getPayoutAccount(), loans.getAmount(), 1);
        if(!isSuccess){
            throw new RuntimeException("支付失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean create(Loans loans){
        // 1. 保存申请表
        this.save(loans);
        repaymentScheduleService.createSchedule(loans);
        return true;
    }

}
